from datetime import datetime

from sqlalchemy import DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, declared_attr, mapped_column


class Base(DeclarativeBase):
  pass


class TimestampMixin:
  created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
  updated_at: Mapped[datetime] = mapped_column(
    DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
  )
  deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)


class BaseEntity(TimestampMixin, Base):
  __abstract__ = True

  @declared_attr.directive
  def __tablename__(cls) -> str:
    return cls.__name__

  id: Mapped[int] = mapped_column(primary_key=True, index=True)
